package com.googlecode.garbagecan.test.socket.sample5;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class MyServer {

	private final static Logger logger = Logger.getLogger(MyServer.class.getName());
	
	public static void main(String[] args) throws Exception {
		if (args.length == 0) {
			return;
		}
		if (args[0].equals("0")) {
			test(false);
		} else if (args[0].equals("1")) {
			test(true);
		} else {
			testStreamSize();
		}
	}

	private static void testStreamSize() throws Exception {
		ServerSocket server = new ServerSocket(10000);
		while (true) {
			final Socket socket = server.accept();
			new Thread(new Runnable() {
				public void run() {
					try {
						InputStream is = socket.getInputStream();
						int size = 0;
						while (true) {
							byte[] bytes = new byte[1024 * 1024];
							int t = is.read(bytes);
							if (t <= 0) {
								break;
							}
							size += t;
						}
						System.out.println(size);
						is.close();
						socket.close();
					} catch(IOException ex) {
						if (!(ex instanceof EOFException)) {
							logger.log(Level.SEVERE, null, ex);
						}
					}
				}
			}).start();
		}
	}
	
	private static void test(final boolean compress) throws Exception {
		ServerSocket server = new ServerSocket(10000);

		while (true) {
			final Socket client = server.accept();
			new Thread(new Runnable() {
				public void run() {
					try {
						GZIPInputStream gzipis = null;
						ObjectInputStream ois = null;
						GZIPOutputStream gzipos = null;
						ObjectOutputStream oos = null;
						if (compress) {
							gzipis = new GZIPInputStream(client.getInputStream());
							ois = new ObjectInputStream(gzipis);
							gzipos = new GZIPOutputStream(client.getOutputStream());
							oos = new ObjectOutputStream(gzipos);
						} else {
							ois = new ObjectInputStream(client.getInputStream());
							oos = new ObjectOutputStream(client.getOutputStream());
						}

						while (true) {
							Object obj = ois.readObject();
							if (obj == null) {
								break;
							}
							BigObject bo = (BigObject)obj;
							logger.log(Level.INFO, bo.toString());
							
							oos.writeObject(bo);
							oos.flush();
							if (compress) {
								gzipos.finish();
							}
						}
						ois.close();
						oos.close();
						client.close();
					} catch (IOException ex) {
						if (!(ex instanceof EOFException)) {
							logger.log(Level.SEVERE, null, ex);
						}
					} catch(ClassNotFoundException ex) {
						logger.log(Level.SEVERE, null, ex);
					}
				}
			}).start();
		}
	}
}
